package com.mo.lib.utils.qrCode

import android.graphics.Bitmap
import com.google.zxing.*
import com.google.zxing.common.HybridBinarizer
import com.xuexiang.xutil.display.ImageUtils
import java.lang.Exception
import java.util.*

/**
 * <pre>
 * desc   : 二维码解析工具类
 * author : xuexiang
 * time   : 2018/5/4 上午12:09
</pre> *
 */

interface AnalyzeCallback {
    /**解析成功 */
    fun onAnalyzeSuccess(bitmap: Bitmap?, result: String)

    /** 解析失败*/
    fun onAnalyzeFailed()
}

/** 二维码最大尺寸*/
val QRCODE_BITMAP_MAX_SIZE = 400

/**
 * 解析二维码（接口回调返回结果）
 *
 * @param QRCodePicPath   二维码图片的路径
 * @param analyzeCallback 解析的回调
 */
fun analyze(QRCodePicPath: String, analyzeCallback: AnalyzeCallback?) {
    val bitmap: Bitmap? = ImageUtils.getBitmap(QRCodePicPath, QRCODE_BITMAP_MAX_SIZE, QRCODE_BITMAP_MAX_SIZE)
    val rawResult: Result? = analyze(bitmap)
    if (rawResult != null) {
        if (analyzeCallback != null) {
            analyzeCallback.onAnalyzeSuccess(bitmap, rawResult.text)
        }
    } else {
        if (analyzeCallback != null) {
            analyzeCallback.onAnalyzeFailed()
        }
    }
}

/**
 * 解析二维码
 *
 * @param bitmap 二维码图片
 * @return 解析结果
 */
fun analyze(bitmap: Bitmap?): Result? {
    val multiFormatReader = MultiFormatReader()

    // 解码的参数
    val hints = Hashtable<DecodeHintType, Any?>(2) // 可以解析的编码类型
    var decodeFormats = Vector<BarcodeFormat?>()
    if (decodeFormats.isEmpty()) {
        decodeFormats = Vector()

        // 这里设置可扫描的类型，我这里选择了都支持
        //            decodeFormats.addAll(DecodeFormatManager.ONE_D_FORMATS);
        //            decodeFormats.addAll(DecodeFormatManager.QR_CODE_FORMATS);
        //            decodeFormats.addAll(DecodeFormatManager.DATA_MATRIX_FORMATS);
    }
    hints[DecodeHintType.POSSIBLE_FORMATS] = decodeFormats // 设置继续的字符编码格式为UTF8
    // hints.put(DecodeHintType.CHARACTER_SET, "UTF8");
    // 设置解析配置参数
    multiFormatReader.setHints(hints)

    // 开始对图像资源解码
    var rawResult: Result? = null
    try {
        rawResult = multiFormatReader.decodeWithState(BinaryBitmap(HybridBinarizer(BitmapLuminanceSource(bitmap!!))))
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return rawResult
}

class BitmapLuminanceSource(bitmap: Bitmap) : LuminanceSource(bitmap.width, bitmap.height) {
    private val bitmapPixels: ByteArray
    init {
        // 首先，要取得该图片的像素数组内容
        val data = IntArray(bitmap.width * bitmap.height)
        bitmapPixels = ByteArray(bitmap.width * bitmap.height)
        bitmap.getPixels(data, 0, width, 0, 0, width, height)

        // 将int数组转换为byte数组，也就是取像素值中蓝色值部分作为辨析内容
        for (i in data.indices) {
            bitmapPixels[i] = data[i].toByte()
        }
    }
    override fun getMatrix(): ByteArray { // 返回我们生成好的像素数据
        return bitmapPixels
    }

    override fun getRow(y: Int, row: ByteArray): ByteArray { // 这里要得到指定行的像素数据
        System.arraycopy(bitmapPixels, y * width, row, 0, width)
        return row
    }
}


